home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
3_0
/
PICTXCMD
/
PICT.C
next >
Wrap
C/C++ Source or Header
|
1989-04-15
|
7KB
|
330 lines
/******************************************************************
PICT XCMD - by Galen Babcock
April 15, 1989
THINK's LightspeedC 3.0 version
Places a QuickDraw generated picture into
the clipboard for pasting from withing
HyperCard. This particular example draws
a plot of y = sin(x)/x into the rectangle.
XCMD NAME: PICT
RESOURCE ID: 403
PICT left,top,right,bottom [,mode[,cycles[,step]]]
INPUT PARAMETERS:
1: left of destination rectangle (required)
2: top of destination rectangle (required)
3: right of destination rectangle (required)
4: bottom of destination rectangle (required)
5: result mode (optional)
default = 1
6: number of cycles to plot (optional)
default = 4
7: pixels per step (optional)
default = 2;
The first four parameters describe the destination rectangle
for the graphic image, and are required. The result mode
parameter can contain one of three legal values...
1 copy picture into scrap and return
2 copy picture into scrap, paste, and return
3 copy picture into scrap, paste, choose browse tool,
and return
Passing "1" for the result mode parameter causes the graphic to
be placed in the scrap. No changes are made to the current
HyperCard card. Passing "2" additionally pastes the image onto
the card, leaving it selected for the user to manipulate with
HyperCard drawing tools (invert, transparent, rotate, etc.).
Passing "3" pastes the image onto the card, and then tells HyperCard
to "Choose browse tool", leaving the image as an integral part
of the card picture.
EXAMPLE USAGE:
PICT 10,10,300,120
PICT 10,10,300,120,3
PICT 10,10,300,120,3,18.2
PICT 10,10,300,120,3,18.2,4
******************************************************************/
#include <math.h>
#include <strings.h>
#include <MacTypes.h>
#include <QuickDraw.h>
#include <ScrapMgr.h>
#include <HyperXCMD.h>
#include <SetUpA4.h>
int errno; /* for math library */
pascal
void main(paramPtr)
XCmdBlockPtr paramPtr;
{
/************************
*
* XCMD variables
*
************************/
GrafPtr currentPort;
Rect dstrect;
PicHandle picH;
char paramvalue[32];
long longvalue;
Boolean showthepen;
int paramindex;
int resmode;
/************************
*
* sin(x)/x plotting variables
*
************************/
double xvalue;
double xstep;
double yscale;
double numcycles;
int ycenter;
int xpos,ypos;
int lastx,lasty;
int numsteps;
/*
*
* A0 points to our code resource, A4 needs to have this
* value to access our global(s).
*
* See pages 84-85 of the THINK C User Manual
*
*/
RememberA0();
SetUpA4();
/*
*
* we need minimally 4 passed parameters
* for the destination rect. Post error
* message and return if not.
*
*/
if ( paramPtr->paramCount < 4 )
{
SendCardMessage(paramPtr,(StringPtr)"\pput \"-- ERROR, Sample Usage: PICT left,top,right,bottom\"");
return;
}
/*
*
* we have at least 4 parameters, put them into the
* left, top, right, bottom coordinates of the
* destination rectangle
*
*/
for (paramindex = 0; paramindex < 4; paramindex++)
{
ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[paramindex]),(StringPtr)¶mvalue);
StringToNum(paramvalue,&longvalue);
switch(paramindex)
{
case 0: dstrect.left = (int)longvalue;
break;
case 1: dstrect.top = (int)longvalue;
break;
case 2: dstrect.right = (int)longvalue;
break;
case 3: dstrect.bottom = (int)longvalue;
break;
}
}
/*
*
* test to see if the destination rect is valid,
* post error message and return if not
*
*/
if ( EmptyRect(&dstrect) )
{
SendCardMessage(paramPtr,(StringPtr)"\pput \"-- ERROR, not a valid rectangle\"");
return;
}
/*
*
* first optional parameter is the result mode, if it is passed,
* store it in local variable "resmode". If not passed or invalid,
* make the default value 1
*
*/
if (paramPtr->paramCount > 4)
{
ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[4]),(StringPtr)¶mvalue);
StringToNum(paramvalue,&longvalue);
resmode = (int)longvalue;
if ( (resmode < 1) || (resmode > 3) )
resmode = 1;
}
else
resmode = 1;
/*
*
* if we have 5 parameters, the optional 5th param is the number
* of sin(x)/x cycles to plot. The parameter must be a
* legal double value. If absent or illegal, default
* to 4.0 cycles
*
*/
if (paramPtr->paramCount > 5)
{
ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[5]),(StringPtr)¶mvalue);
StrToExt(paramPtr,(unsigned char *)paramvalue,&numcycles);
if (numcycles <= 0.0)
numcycles = 4.0;
}
else
numcycles = 4.0;
/*
*
* if we have 7 parameters, the 7th parameter is the number of
* pixel steps to make for each plot point. Smaller values result
* in higher resolution, larger values result in a "jagged" plot
*
*/
if (paramPtr->paramCount > 6)
{
ZeroToPas(paramPtr,(unsigned char *)*(paramPtr->params[6]),(StringPtr)¶mvalue);
StringToNum(paramvalue,&longvalue);
numsteps = (int)longvalue;
if ( (numsteps < 1) || (numsteps > 32) )
numsteps = 2;
}
else
numsteps = 2;
/*
*
* create a QuickDraw PicHandle to do our
* drawing into
*
*/
picH = OpenPicture(&dstrect);
/*
*
* uncomment the next line to allow the HyperCard user
* to see the drawing taking place.
*
*/
/* ShowPen(); */
PenNormal();
/*
*
* begin drawing our image...
*
*/
EraseRect(&dstrect);
FrameRect(&dstrect);
dstrect.bottom -= 1;
dstrect.right -= 1;
/*
*
* how much does "x" change for each step?
*
*/
xstep = numsteps * ( 2.0 * numcycles * PI ) / (dstrect.right - dstrect.left) ;
/*
*
* set up coordinate system relative to our
* destination rectangle
*
*/
ycenter = dstrect.top + (dstrect.bottom - dstrect.top) / 2;
yscale = (dstrect.bottom - dstrect.top) / 2;
xpos = dstrect.left;
lastx = xpos;
lasty = ycenter;
MoveTo(lastx,lasty);
/*
*
* for each iteration, calculate the pixel value of "y",
* and draw a line from the last x,y pair to the new
* x,y pair
*
*/
for ( xvalue = -numcycles * PI; xvalue < ( numcycles * PI); xvalue += xstep )
{
ypos = ycenter + (int)(yscale * sin(xvalue)/xvalue);
MoveTo(lastx,lasty);
LineTo(xpos,ypos);
lastx = xpos;
lasty = ypos;
xpos += numsteps;
SendCardMessage(paramPtr,(StringPtr)"\pset cursor to busy");
}
/*
*
* our drawing is complete, so...
*
*/
ClosePicture();
/*
*
* place our QuickDraw PICT into the scrap (clipboard) and
* if all is successful, tell HyperCard to paste the
* the picture.
*
*/
if ( (longvalue = LoadScrap()) == noErr )
{
if ( (longvalue = ZeroScrap()) == noErr )
{
HLock((Handle)picH);
longvalue = PutScrap(GetHandleSize(picH),'PICT',*picH);
HUnlock((Handle)picH);
if (resmode > 1)
{
SendCardMessage(paramPtr,(StringPtr)"\pdomenu Paste Picture");
if (resmode > 2)
SendCardMessage(paramPtr,(StringPtr)"\pchoose browse tool");
}
}
}
/*
*
* release the memory occupied by our
* QuickDraw PicHandle, and restore
* registers
*
*/
KillPicture(picH);
RestoreA4();
}